
package ybu.wt.gateway.config;

import com.alibaba.fastjson.JSON;
import io.jsonwebtoken.Claims;
import io.jsonwebtoken.Jwts;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.cloud.gateway.filter.GatewayFilterChain;
import org.springframework.cloud.gateway.filter.GlobalFilter;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.Ordered;
import org.springframework.http.HttpStatus;
import org.springframework.http.server.reactive.ServerHttpRequest;
import org.springframework.stereotype.Component;
import org.springframework.web.server.ServerWebExchange;
import reactor.core.publisher.Mono;
import ybu.wt.gateway.common.EncryptUtil;

import java.nio.charset.StandardCharsets;
import java.util.HashMap;
import java.util.List;
import java.util.Map;


/**
 * @author w.tao wangtao@tenm.com.cn
 * @date 14:21 2019/12/19
 */

@Component
public class TokenFilter implements GlobalFilter, Ordered {
    Logger logger = LoggerFactory.getLogger(TokenFilter.class);
    private String SIGNING_KEY = "uaa123";
    @Override
    public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
            String token = exchange.getRequest().getHeaders().get("token").get(0);
            System.out.println("token : " + token);
            if (token == null || token.isEmpty()) {
                logger.info("token 为空，无法进行访问.");
                exchange.getResponse().setStatusCode(HttpStatus.UNAUTHORIZED);
                return exchange.getResponse().setComplete();
            }
            Object username = null;
            List<String> authorities = null;
            try {
                //解析jwt
                Claims claims = Jwts.parser().setSigningKey(SIGNING_KEY.getBytes(StandardCharsets.UTF_8)).parseClaimsJws(token).getBody();
                username = claims.get("user_name");
                authorities = (List) claims.get("authorities");
            } catch (Exception e) {
                logger.warn("token 错误，无法解析！");
            }
            //判断token是否可以解析出用户信息，不能则返回未认证
            if (username == null) {
                exchange.getResponse().setStatusCode(HttpStatus.UNAUTHORIZED);
                return exchange.getResponse().setComplete();
            }
            Map<String, Object> jsonToken = new HashMap<>();
            jsonToken.put("username", username);
            jsonToken.put("authorities", authorities);

            //向headers中放文件，记得build
            ServerHttpRequest host = exchange.getRequest().mutate().header("json-Token", EncryptUtil.encodeUTF8StringBase64(JSON.toJSONString(jsonToken))).build();
            //将现在的request 变成 change对象
            ServerWebExchange build = exchange.mutate().request(host).build();

            return chain.filter(build);
    }

    @Override
    public int getOrder() {
        return 10;
    }
}
